#ifndef CITIZEN_HPP_INCLUDED
#define CITIZEN_HPP_INCLUDED

#include <map>
#include <string>

#include "citizen_fwd.hpp"
#include "formula_callable.hpp"
#include "government.hpp"
#include "job.hpp"
#include "resource_fwd.hpp"
#include "wml_node_fwd.hpp"

namespace hex {
class tile;
}

class barter_market;
class money_market;
class occupation;
class rng;

class citizen : public game_logic::formula_callable
{
public:
	static void init(wml::const_node_ptr node);
	static int rate_tile(const hex::tile& t);

	citizen();
	~citizen();

	void set_allegiance(const government_ptr& gov);
	const government_ptr& allegiance() const { return allegiance_; }

	bool reproduces() const;
	bool survives(std::string* death_reason) const;

	const resource* produce(const hex::tile& t) const;

	int items_owned(const std::string& name) const;
	void get_item(const std::string& name, int quantity);
	void all_items(std::map<std::string, int>& items) const;
	void process_item_spoilage();

	std::string text_description() const;

	void place_orders(barter_market& m);
	void place_orders(money_market& m);

	void level_up(const_resource_ptr specialization);
	int production_bonus(const_resource_ptr resource) const;

	int would_accept_job(const_job_ptr j, const money_market& m, const hex::tile& t, int rank) const;
	void set_job(job_ptr j) { job_ = j; }
	job_ptr job() { return job_; }
	bool has_job() const { return job_.get(); }

	const occupation* get_occupation() const { return occupation_; }
	void change_occupation(const occupation* o) { occupation_ = o; }
	int would_change_occupation(const occupation& o, const money_market& m, const hex::tile& t, int rank) const;

	void cultural_conversion(citizen& other) const;

	void draw(rng& rng, double x, double y, double z) const;
private:
	int production_rating(const hex::tile& t, const const_resource_ptr& resource, int quality) const;
	variant get_value(const std::string& key) const;

	int age_;
	std::map<std::string, int> items_;
	const_resource_ptr specialization_;
	int level_;
	job_ptr job_;
	const occupation* occupation_;
	government_ptr allegiance_;
};

#endif
